package org.example.edusmart.controller.Login;

import lombok.val;
import org.example.edusmart.pojo.LoginUserPojo;
import org.example.edusmart.pojo.UserPojo;
import org.example.edusmart.request.login.ChangePasswordPojo;
import org.example.edusmart.request.login.LoginPojo;
import org.example.edusmart.service.UserService;
import org.example.edusmart.utils.JwtUtils;
import org.example.edusmart.utils.RedisUtils;
import org.example.edusmart.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Objects;


@RestController
@RequestMapping("/user")
public class LoginController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UserService userService;

    @Autowired
    private PasswordEncoder bCryptPasswordEncoder;

    /**
     * 登录操作
     * @param user 前端传值
     * @return 状态码，token
     */
    @PostMapping("/login/")
    public Result login(@RequestBody LoginPojo user) {

        // 验证用户 通过 AuthenticationManager
        val authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("登录失败");
        }
        // 获取用户信息
        LoginUserPojo principal = (LoginUserPojo) authenticate.getPrincipal();
        //认证通过 生成token
        val s = jwtUtils.generateJwt(principal.getUser().getUserId());

        // 存入redis
        redisUtils.setObject("login:" + principal.getUser().getUserId(), principal);
        // 返回token
        HashMap<String, Object> returnData = new HashMap<>() {{
            put("token", s);
        }};
        return new Result(returnData,200 , "请求通过");
    }

    /**
     * 退出登录
     * @return 状态码
     */
    @PreAuthorize("hasAuthority('public_permission')") //指明有公共权限的才能访问
    @PostMapping("/logout/")
    public Result logout() {
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();

        LoginUserPojo principal = (LoginUserPojo) authentication.getPrincipal();
        // 清除redis
        redisUtils.delObject("login:" + principal.getUser().getUserId());
        return new Result(200,"退出成功");
    }

    /**
     * 登录前忘记密码
     * @param user 前端入参
     * @return 状态码
     */
    @PostMapping("/changePassword/")
    public Result LoginAlterPassword(@RequestBody ChangePasswordPojo user){
        UserPojo a = userService.checkEmail(user.getEmail());
        if (Objects.isNull(a)) {
            return new Result(404,"账号不存在");
        }
        if (!user.getNewPassword().equals(user.getConfirmPassword())) {
            return new Result(404, "两次密码输入不一致");
        }
        if (user.getCode().isEmpty()) {
            return new Result(404, "请输入验证码");
        }
        //替换密码，把新密码加密
        HashMap<String, Object> insertData = new HashMap<>() {{
            put("email", user.getEmail());
            put("newPassword",bCryptPasswordEncoder.encode(user.getNewPassword()));
        }};
        userService.changePassword(insertData);
        return new Result(200,"修改成功");
    }
}